/**
 * 密钥管理器
 * 负责团队密钥的获取、缓存和管理
 * 
 * @author RickPan Team
 * @version 1.0
 * @since 2025-07-19
 */

import { request } from '@/utils/request'
import teamKeyApi, { type TeamKeyResponse } from '@/api/teamKey'
import type { EncryptionHealthStatus, KeyCacheStats } from '@/types/encryption'

import type { TeamKeyInfo, KeyCacheEntry } from '@/types/encryption'

// 重新导出类型以保持向后兼容
export type { TeamKeyInfo, KeyCacheEntry }

/**
 * 密钥管理核心类
 */
export class KeyManager {
  private static instance: KeyManager
  private keyCache = new Map<number, KeyCacheEntry>()
  private readonly CACHE_TTL = 30 * 60 * 1000 // 30分钟缓存时间
  private readonly MAX_CACHE_SIZE = 50 // 最大缓存50个团队的密钥
  private readonly CLEANUP_INTERVAL = 5 * 60 * 1000 // 5分钟清理一次过期缓存

  private constructor() {
    this.startCacheCleanup()
  }

  /**
   * 获取单例实例
   */
  static getInstance(): KeyManager {
    if (!KeyManager.instance) {
      KeyManager.instance = new KeyManager()
    }
    return KeyManager.instance
  }

  /**
   * 获取团队密钥
   * 
   * @param teamId 团队ID
   * @param forceRefresh 是否强制刷新
   * @returns 团队密钥
   */
  async getTeamKey(teamId: number, forceRefresh: boolean = false): Promise<string> {
    try {
      // 1. 检查缓存
      if (!forceRefresh) {
        const cachedKey = this.getCachedKey(teamId)
        if (cachedKey) {
          console.debug(`🔑 使用缓存的团队密钥: teamId=${teamId}`)
          return cachedKey.keyInfo.teamKey
        }
      }

      // 2. 从服务器获取密钥
      console.debug(`🔍 从服务器获取团队密钥: teamId=${teamId}`)
      const keyResponse: TeamKeyResponse = await teamKeyApi.getCurrentKey(teamId)

      // 3. 构建密钥信息
      const keyInfo: TeamKeyInfo = {
        teamKey: keyResponse.encryptedKey,
        algorithm: keyResponse.algorithm,
        keyLength: keyResponse.keyLength,
        fetchedAt: Date.now(),
        expiresAt: keyResponse.expiresAt
      }

      // 4. 缓存密钥
      this.cacheKey(teamId, keyInfo)

      console.debug(`✅ 团队密钥获取成功: teamId=${teamId}`)
      return keyInfo.teamKey

    } catch (error) {
      console.error(`❌ 获取团队密钥失败: teamId=${teamId}`, error)
      throw new Error(`获取团队密钥失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
  }

  /**
   * 预加载团队密钥
   * 
   * @param teamIds 团队ID列表
   */
  async preloadTeamKeys(teamIds: number[]): Promise<void> {
    const promises = teamIds.map(teamId => 
      this.getTeamKey(teamId).catch(error => {
        console.warn(`⚠️ 预加载团队密钥失败: teamId=${teamId}`, error)
        return null
      })
    )

    await Promise.allSettled(promises)
    console.debug(`🚀 预加载完成，成功加载 ${teamIds.length} 个团队密钥`)
  }

  /**
   * 轮换团队密钥
   * 
   * @param teamId 团队ID
   * @returns 新的团队密钥
   */
  async rotateTeamKey(teamId: number): Promise<string> {
    try {
      console.debug(`🔄 开始轮换团队密钥: teamId=${teamId}`)

      const keyResponse: TeamKeyResponse = await teamKeyApi.rotateKey(teamId)

      // 更新缓存
      const keyInfo: TeamKeyInfo = {
        teamKey: keyResponse.encryptedKey,
        algorithm: keyResponse.algorithm,
        keyLength: keyResponse.keyLength,
        fetchedAt: Date.now(),
        expiresAt: keyResponse.expiresAt
      }

      this.cacheKey(teamId, keyInfo)

      console.debug(`✅ 团队密钥轮换成功: teamId=${teamId}`)
      return keyInfo.teamKey

    } catch (error) {
      console.error(`❌ 轮换团队密钥失败: teamId=${teamId}`, error)
      throw new Error(`轮换团队密钥失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
  }

  /**
   * 从缓存获取密钥
   */
  private getCachedKey(teamId: number): KeyCacheEntry | null {
    const entry = this.keyCache.get(teamId)
    
    if (!entry) {
      return null
    }

    // 检查是否过期
    const now = Date.now()
    if (now - entry.keyInfo.fetchedAt > this.CACHE_TTL) {
      this.keyCache.delete(teamId)
      return null
    }

    // 更新使用统计
    entry.lastUsed = now
    entry.hitCount++

    return entry
  }

  /**
   * 缓存密钥
   */
  private cacheKey(teamId: number, keyInfo: TeamKeyInfo): void {
    // 检查缓存大小，如果超过限制则清理最少使用的
    if (this.keyCache.size >= this.MAX_CACHE_SIZE) {
      this.evictLeastUsedKey()
    }

    const entry: KeyCacheEntry = {
      keyInfo,
      lastUsed: Date.now(),
      hitCount: 1
    }

    this.keyCache.set(teamId, entry)
  }

  /**
   * 清理最少使用的密钥
   */
  private evictLeastUsedKey(): void {
    let leastUsedTeamId: number | null = null
    let leastUsedCount = Infinity
    let oldestTime = Infinity

    for (const [teamId, entry] of this.keyCache.entries()) {
      if (entry.hitCount < leastUsedCount || 
          (entry.hitCount === leastUsedCount && entry.lastUsed < oldestTime)) {
        leastUsedTeamId = teamId
        leastUsedCount = entry.hitCount
        oldestTime = entry.lastUsed
      }
    }

    if (leastUsedTeamId !== null) {
      this.keyCache.delete(leastUsedTeamId)
      console.debug(`🗑️ 清理最少使用的密钥缓存: teamId=${leastUsedTeamId}`)
    }
  }

  /**
   * 启动缓存清理定时器
   */
  private startCacheCleanup(): void {
    setInterval(() => {
      this.cleanupExpiredKeys()
    }, this.CLEANUP_INTERVAL)
  }

  /**
   * 清理过期的密钥缓存
   */
  private cleanupExpiredKeys(): void {
    const now = Date.now()
    const expiredKeys: number[] = []

    for (const [teamId, entry] of this.keyCache.entries()) {
      if (now - entry.keyInfo.fetchedAt > this.CACHE_TTL) {
        expiredKeys.push(teamId)
      }
    }

    expiredKeys.forEach(teamId => {
      this.keyCache.delete(teamId)
    })

    if (expiredKeys.length > 0) {
      console.debug(`🧹 清理过期密钥缓存: ${expiredKeys.length} 个`)
    }
  }

  /**
   * 清空指定团队的密钥缓存
   * 
   * @param teamId 团队ID
   */
  clearTeamKeyCache(teamId: number): void {
    this.keyCache.delete(teamId)
    console.debug(`🗑️ 清空团队密钥缓存: teamId=${teamId}`)
  }

  /**
   * 清空所有密钥缓存
   */
  clearAllKeyCache(): void {
    const size = this.keyCache.size
    this.keyCache.clear()
    console.debug(`🗑️ 清空所有密钥缓存: ${size} 个`)
  }

  /**
   * 获取缓存统计信息
   */
  getCacheStats(): {
    size: number
    maxSize: number
    cacheTTL: number
    entries: Array<{
      teamId: number
      algorithm: string
      fetchedAt: number
      lastUsed: number
      hitCount: number
      age: number
    }>
  } {
    const now = Date.now()
    const entries = Array.from(this.keyCache.entries()).map(([teamId, entry]) => ({
      teamId,
      algorithm: entry.keyInfo.algorithm,
      fetchedAt: entry.keyInfo.fetchedAt,
      lastUsed: entry.lastUsed,
      hitCount: entry.hitCount,
      age: now - entry.keyInfo.fetchedAt
    }))

    return {
      size: this.keyCache.size,
      maxSize: this.MAX_CACHE_SIZE,
      cacheTTL: this.CACHE_TTL,
      entries
    }
  }

  /**
   * 检查加密服务健康状态
   */
  async checkEncryptionHealth(): Promise<EncryptionHealthStatus> {
    try {
      // 使用一个测试团队ID来检查加密健康状态
      // 这里可以使用当前用户的第一个团队，或者创建专门的健康检查API
      const testTeamId = 1 // 临时使用固定ID，实际应该动态获取
      const healthStatus = await teamKeyApi.getKeyHealth(testTeamId)

      return {
        healthy: healthStatus.healthy,
        algorithm: healthStatus.algorithm || 'AES-256-GCM',
        checkTime: healthStatus.checkTime,
        error: healthStatus.healthy ? undefined : healthStatus.message
      }
    } catch (error) {
      return {
        healthy: false,
        algorithm: 'unknown',
        checkTime: Date.now(),
        error: error instanceof Error ? error.message : '未知错误'
      }
    }
  }
}
